package com.ckx.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ckx.constants.SystemConstants;
import com.ckx.domain.dto.CategoryAddDto;
import com.ckx.domain.dto.CategoryUpdateDto;
import com.ckx.domain.vo.CategoryUpdateVo;
import com.ckx.domain.entity.Article;
import com.ckx.domain.entity.Category;
import com.ckx.domain.vo.CategoryVo;
import com.ckx.domain.vo.PageVo;
import com.ckx.enums.AppHttpCodeEnum;
import com.ckx.exception.SystemException;
import com.ckx.mapper.CategoryMapper;
import com.ckx.service.ArticleService;
import com.ckx.service.CategoryService;
import com.ckx.utils.BeanCopyUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> implements CategoryService {

    @Autowired
    private ArticleService articleService;

    @Override
    public List<CategoryVo> getCategoryList() {

        //查询文章表  状态为已发布的文章
        QueryWrapper<Article> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(Article::getStatus, SystemConstants.ARTICLE_STATUS_NORMAL);
        List<Article> articles = articleService.list(wrapper);
        //获取文章的分类id，并且去重(此时获得了一个已发布并且去重的 categoryIds)
        Set<Long> categoryIds = articles.stream()
                .map(Article::getCategoryId)
                .collect(Collectors.toSet());

        //查询分类表
        List<Category> categories = this.listByIds(categoryIds);
        List<Category> categoryList = categories.stream().filter(category -> {
            return category.getStatus().equals(SystemConstants.STATUS_NORMAL);
        }).collect(Collectors.toList());
        //封装成 vo
        List<CategoryVo> categoryVos = BeanCopyUtil.copyBeanList(categoryList, CategoryVo.class);

        return categoryVos;
    }

    @Override
    public List<CategoryVo> listAllCategory() {

        QueryWrapper<Category> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(Category::getDelFlag, SystemConstants.NOT_DELFLAG);
        List<Category> categories = this.baseMapper.selectList(wrapper);
        return categories.stream()
                .map(category -> BeanCopyUtil.copyBean(category, CategoryVo.class))
                .collect(Collectors.toList());
    }

    @Override
    public PageVo listByPage(Integer pageNum, Integer pageSize, Category category) {
        QueryWrapper<Category> wrapper = new QueryWrapper<>();
        wrapper.lambda().like(StringUtils.hasText(category.getName()), Category::getName, category.getName());
        wrapper.lambda().eq(StringUtils.hasText(category.getStatus()), Category::getStatus, category.getStatus());

        Page<Category> page = new Page<>(pageNum, pageSize);
        page(page, wrapper);

        List<CategoryVo> categoryVos = BeanCopyUtil.copyBeanList(page.getRecords(), CategoryVo.class);

        return new PageVo(categoryVos, page.getTotal());
    }

    @Override
    public void addCategory(CategoryAddDto categoryAddDto) {
        Category category = BeanCopyUtil.copyBean(categoryAddDto, Category.class);
        category.setPid(SystemConstants.DEFAULT_PARENT);
        this.save(category);
    }

    @Override
    public CategoryUpdateVo getCategoryInfo(Long id) {
        if (null == id || id <= 0) {
            throw new SystemException(AppHttpCodeEnum.ARGS_FAIL);
        }
        Category category = this.getById(id);
        if (Objects.isNull(category)) {
            throw new SystemException(AppHttpCodeEnum.ARGS_FAIL);
        }
        return BeanCopyUtil.copyBean(category, CategoryUpdateVo.class);
    }

    @Override
    public void updateCategory(CategoryUpdateDto categoryUpdateDto) {
        Category category = BeanCopyUtil.copyBean(categoryUpdateDto, Category.class);
        this.updateById(category);
    }

    @Override
    public void del4DelFlag(Long id) {
        UpdateWrapper<Category> wrapper = new UpdateWrapper<>();
        wrapper.lambda().set(Category::getDelFlag, SystemConstants.DELFLAG);
        wrapper.lambda().eq(Category::getId, id);
        this.update(wrapper);
    }
}
